#include "ClientBase.h"

using namespace std;


ClientBase::ClientBase(FenetreClient *ptrFenetre)
{
    connecte = false;
    activite = 0;
    this->ptrFenetre = ptrFenetre;
}

ClientBase::~ClientBase()
{
    fermerSocket("Destruction de clientBase");
}

bool ClientBase::ouvrirSocket(const char *ip, const char *port)
{
    activite = 0;
    this->port = port;
    this->ip = ip;
    info = gethostbyname(this->ip);
    if(info)
    {
        serveur.sin_family = AF_INET;
        serveur.sin_addr.s_addr = htonl(ntohl(* (uint32_t *)info->h_addr));
        serveur.sin_port = htons(atoi(this->port));
        this->sock = socket(PF_INET, SOCK_STREAM, 0);
        if(sock >= 0)
        {
            if(!::connect(this->sock, (struct sockaddr *) &serveur, sizeof(serveur)))
            {
                connecte = true;
                pthread_create(&threadLecture, NULL, thread_attendreMessage, (void *)this);
                return true;
            }
        }
    }
    return false;
}

void ClientBase::fermerSocket(const QString &cause)
{
    if(connecte) emit estDeconnecte(cause);
    connecte = false;
    shutdown(sock, 2);
    close(sock);
}

void ClientBase::attendreMessage()
{
    ecrireMessage(ETUD_LOGIN, ptrFenetre->getLogin());
    int idMessage;
    while(connecte)
    {
        idMessage = lireEntierUnOctet();
        if(idMessage == 0) fermerSocket("Connexion au serveur perdue.");
        else traitementMessage(idMessage);
    }
}

void ClientBase::traitementMessage(int idMessage) // renvoie 0 si le message recu mais fin a la connexion avec le serveur.
{
    switch(idMessage)
    {
    case ETUD_ERR_LOGIN:
        {
            ptrFenetre->seDeconnecter("Login invalide");
            break;
        }
    case ETUD_LISTE:
        {
            emit estConnecte(); // On informe la fenetreClient que le client est connecté.

            QStringList listeSalles = stringListToQStringList(lireListeChaines());
            emit sallesRecues(listeSalles);
            break;
        }
    case ETUD_ERR_CHOIXSALLE:
        ptrFenetre->ecrireConsole2("Salle choisie non valide.");
        break;
    case ETUD_OK_CHOISALLE:
        {
            QStringList listeActivites = stringListToQStringList(lireListeChaines());
            emit activitesRecues(listeActivites);
            break;
        }
    case ETUD_ERR_CHOIX_ACTIVITE:
        ptrFenetre->ecrireConsole2("Activité choisie non valide.");
        break;
    case ETUD_OK_CHOIX_ACTIVITE:

        break;
    case AST_MSG:
        {
            string message = lireChaine();
            ptrFenetre->ecrireMessageChat(QString::fromStdString(message));
            break;
        }
    case AST_VOIP:

        break;
    case ETUD_QCM:
        {
            string questionTmp = lireChaine();
            list<string> reponseTmp = lireListeChaines();

            if(activite == 0) // Lancement de l'activité.
            {
                activite = 2;
                emit sig_lancerActivite(2);
            }
            if(activite == 2)
            {
                QString question = QString::fromStdString(questionTmp);
                QStringList reponses;
                int nbChaines = reponseTmp.size();
                for(int i = 0; i < nbChaines; ++i)
                {
                    reponses.append(QString::fromStdString(reponseTmp.front()));
                    reponseTmp.pop_front();
                }
                emit sig_nouvelleQuestionQCM(question, reponses);
            }
            break;
        }
    case ETUD_Q2:

        break;
    case ETUD_Q3:

        break;
    case ETUD_Q4:

        break;
    case ETUD_OBS_Q4:

        break;
    case ETUD_FIN_ACTIVITE:
        if(activite)
        {
            emit sig_arreterActivite(activite);
            activite = 0;
        }
        break;
    }
}

bool ClientBase::getConnecte()
{
    return connecte;
}

const char *ClientBase::getPort()
{
    return port;
}

const char *ClientBase::getIp()
{
    return ip;
}

pthread_t ClientBase::getThreadLecture()
{
    return threadLecture;
}
